import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext, ttk
import re
import requests
import os
import hashlib
import random
import threading
import time
import webbrowser


def translate_text(phrases, service='Google'):
    if service == 'Google':
        try:
            api_url = 'https://translate.googleapis.com/translate_a/single'
            params = {
                'client': 'gtx',
                'dt': 't',
                'sl': 'ja',
                'tl': 'en',
                'q': '\n'.join(phrases).strip()
            }
            response = requests.get(api_url, params=params)  # 返回的json文件
            if response.status_code == 200:
                translations = response.json()[0]
                translated_phrases = [item[0].replace('\n', ' ').strip() for item in translations if item[0]]
                return translated_phrases
            else:
                messagebox.showerror('翻译错误', f'请求失败，状态码：{response.status_code}')
                return []
        except Exception as e:
            messagebox.showerror('翻译异常', f'翻译时发生错误 Error occur when translating: ：{e}')
            return []
    elif service == 'Baidu':
        try:
            # Baidu Translate API details
            appid = '20231119001885137'
            key = 'oEw3A1pSQE1xVywy8jkE'
            api_url = 'https://api.fanyi.baidu.com/api/trans/vip/translate'
            from_lang = 'jp'
            to_lang = 'en'
            salt = random.randint(32768, 65536)

            # Join phrases with newline characters
            query = '\n'.join(phrases).strip()

            # Generate sign
            str_to_sign = appid + query + str(salt) + key
            sign = hashlib.md5(str_to_sign.encode()).hexdigest()

            # Set up request parameters
            params = {
                'q': query,
                'appid': appid,
                'salt': salt,
                'from': from_lang,
                'to': to_lang,
                'sign': sign
            }

            # Make the request
            response = requests.get(api_url, params=params)
            # print("Response from Baidu API:", response.json())

            # Process the response
            if response.status_code == 200:
                translations = response.json().get('trans_result')
                if translations:
                    translated_phrases = [item['dst'] for item in translations]
                    return translated_phrases
                else:
                    return []
            else:
                messagebox.showerror('Translation Error 翻译错误',
                                     f'Request failed, status code: 请求失败，状态码：{response.status_code}')
                return []
        except Exception as e:
            messagebox.showerror('Translation Exception 翻译异常',
                                 f'An error occurred during translation: 翻译时发生错误：{e}')
            return []
    else:
        raise ValueError("Unsupported translation service")


class KatakanaTranslatorApp:
    def __init__(self, root):
        self.translation_done = False
        self.translation_service = 'Google'
        self.translated_content = None
        self.content = None
        self.root = root
        self.create_widgets()
        self.language = 'Chinese'  # Default language
        self.messages = {
            'Chinese': {
                'open_file': '选择文件',
                'adjust_output': '调整输出模式',
                'settings': '设置',
                'save_translated_results': '保存翻译结果',
                'highlight_katakana': '高亮片假名',
            },
            'English': {
                'open_file': 'Open File',
                'adjust_output': 'Adjust Output Mode',
                'settings': 'Settings',
                'save_translated_results': 'Save Translated Results',
                'highlight_katakana': 'Highlight Katakana',
            }
        }
        self.katakana_words = None
        self.katakana_pattern = None
        self.bracket_style = ('(', ')')  # Default bracket style


    def create_widgets(self):
        button_frame = tk.Frame(self.root)
        button_frame.pack(side=tk.LEFT, padx=10, pady=10, fill=tk.Y)

        self.btn_open_file = tk.Button(button_frame, text='选择文件', command=self.load_file)
        self.btn_open_file.pack(side=tk.TOP, fill=tk.X, pady=15)

        self.btn_output_mode = tk.Button(button_frame, text='调整输出模式', command=self.open_output_mode_dialog)
        self.btn_output_mode.pack(side=tk.TOP, fill=tk.X, pady=15)

        self.btn_settings = tk.Button(button_frame, text='设置', command=self.open_settings_dialog)
        self.btn_settings.pack(side=tk.TOP, fill=tk.X, pady=15)

        # Text widget for previewing files
        self.preview_text = scrolledtext.ScrolledText(self.root, state='disabled')
        self.preview_text.pack(expand=True, fill='both')

        # Add Save button to save the translated content after previewing
        self.btn_save_translated = tk.Button(self.root, text='保存翻译结果', command=self.save_translated_file)
        self.btn_save_translated.pack(side=tk.LEFT, padx=10, pady=10)

        # Checkbutton for toggling katakana highlight
        self.highlight_var = tk.BooleanVar()
        self.btn_highlight = tk.Checkbutton(self.root, text='高亮片假名', variable=self.highlight_var,
                                            command=self.toggle_highlight)
        self.btn_highlight.pack(side=tk.LEFT, padx=10, pady=10)

        # Configure tag for katakana highlighting
        self.preview_text.tag_configure('katakana_highlight', background='yellow')

        # 创建右键菜单
        self.context_menu = tk.Menu(self.root, tearoff=0)
        self.context_menu.add_command(label="搜索图片", command=self.search_image)

        # 绑定右键点击事件到预览器文本小部件
        self.preview_text.bind("<Button-3>", self.on_right_click)

        self.lbl_translation_service = tk.Label(self.root, text='当前翻译服务(Current translator API): Google')
        self.lbl_translation_service.pack(side=tk.BOTTOM, fill=tk.X)

    def load_file(self):
        filepath = filedialog.askopenfilename()
        if not filepath:
            return

        self.filepath = filepath  # Store the filepath for later use in saving
        supported_types = ['.txt']
        if any(filepath.lower().endswith(ext) for ext in supported_types):
            with open(filepath, 'r', encoding='utf-8') as file:
                self.content = file.read()
            self.translate_and_preview()  # Automatically translate and preview
        else:
            messagebox.showwarning('File Type Check 文件类型检查', 'Not Supported File Type! 不支持的文件类型！')

    def translate_and_preview(self):
        # Extract katakana words and translate them
        self.katakana_pattern = re.compile(r"([\u30A1-\u30FA\u30FD-\u30FFー]{2,})(\s*)")
        matches = re.findall(self.katakana_pattern, self.content)  # 使用集合去重
        self.katakana_words = set(match[0] for match in matches)  # extract just the katakana phrases

        if not self.katakana_words:
            messagebox.showinfo('片假名检测', '未检测到片假名单词。')
            return

        self.translation_done = False
        self.translation_thread = threading.Thread(target=self.start_translation_thread,
                                                   args=(list(self.katakana_words),))
        self.translation_thread.start()
        self.progress_thread = threading.Thread(target=self.show_progress_bar)
        self.progress_thread.start()

    def start_translation_thread(self, phrases):
        translated_phrases = translate_text(list(self.katakana_words), service=self.translation_service)
        self.translations = dict(zip(self.katakana_words, translated_phrases))

        # 替换文本中的片假名单词为原文加上翻译

        self.translated_content = re.sub(self.katakana_pattern, self.repl, self.content)
        self.translation_done = True
        self.update_preview_widget()

    def repl(self, match):
        word = match.group(0)
        translation = self.translations.get(word, '???')
        # Use instance attribute for bracket style
        return f"{word}{self.bracket_style[0]}{translation}{self.bracket_style[1]}"

    def show_progress_bar(self):
        self.progress_window = tk.Toplevel(self.root)
        self.progress_window.title("翻译中... translating...")
        self.progressbar = ttk.Progressbar(self.progress_window, orient=tk.HORIZONTAL, length=300, mode='determinate')
        self.progressbar.pack(pady=20)
        self.progressbar['maximum'] = 100  # Set the maximum value of progress bar to 100
        self.progress_window.update()

        while not self.translation_done:
            # Update the progress bar value here
            time.sleep(0.04)
            # Ensure progress bar does not exceed 99% until translation is done
            if self.progressbar['value'] < 99:
                self.progressbar['value'] += 1
            self.progress_window.update_idletasks()
        self.progressbar['value'] = 100
        self.progress_window.destroy()

    def update_preview_widget(self):
        # Make sure to run this on the main thread if it changes the GUI
        self.preview_text.config(state='normal')
        self.preview_text.delete('1.0', tk.END)
        self.preview_text.insert('1.0', self.translated_content)
        self.preview_text.config(state='normal')

    def save_translated_file(self):
        save_path = filedialog.asksaveasfilename(
            initialdir=os.path.dirname(self.filepath),
            title="Save File... 另存为...",
            filetypes=(("Text files", "*.txt"), ("All files", "*.*")),
            defaultextension=".txt"
        )
        if save_path:
            # Get the current content from the preview_text widget
            current_content = self.preview_text.get('1.0', tk.END)
            with open(save_path, 'w', encoding='utf-8') as save_file:
                save_file.write(current_content)
            messagebox.showinfo('保存文件', f'文件已另存为：{save_path}')

    def toggle_highlight(self):
        # Apply or remove highlighting based on the Checkbutton state
        if self.highlight_var.get():
            self.apply_highlight()
        else:
            self.remove_highlight()

    def apply_highlight(self):
        katakana_pattern = r"[\u30A1-\u30FA\u30FD-\u30FFー]+"
        self.preview_text.config(state='normal')
        start = '1.0'
        while True:
            match_start = self.preview_text.search(katakana_pattern, start, tk.END, regexp=True)
            if not match_start:
                break
            # Find the end of the matched word
            word = self.preview_text.get(match_start, f"{match_start} lineend")
            match_length = len(re.match(katakana_pattern, word).group(0))
            match_end = f"{match_start}+{match_length}c"
            self.preview_text.tag_add('katakana_highlight', match_start, match_end)
            # Move to the end of the current match to find next
            start = match_end
        self.preview_text.config(state='normal')

    def remove_highlight(self):
        self.preview_text.tag_remove('katakana_highlight', '1.0', tk.END)

    def switch_language(self, language):
        self.language = language
        self.update_language()

    def switch_translation_service(self, service):
        self.translation_service = service
        self.lbl_translation_service.config(text=f'当前翻译服务(Current translator API): {service}')

    def update_language(self):
        # Update all widget texts to the current language
        self.btn_open_file.config(text=self.messages[self.language]['open_file'])
        self.btn_output_mode.config(text=self.messages[self.language]['adjust_output'])
        self.btn_settings.config(text=self.messages[self.language]['settings'])
        self.btn_save_translated.config(text=self.messages[self.language]['save_translated_results'])
        self.btn_highlight.config(text=self.messages[self.language]['highlight_katakana'])
        # ... update other widgets as needed ...

    def open_settings_dialog(self):
        settings_window = tk.Toplevel(self.root)
        settings_window.title('设置')

        tk.Button(settings_window, text='切换到中文', command=lambda: self.switch_language('Chinese')).pack()
        tk.Button(settings_window, text='Switch to English', command=lambda: self.switch_language('English')).pack()
        tk.Button(settings_window, text='使用谷歌翻译，Use Google translate API',
                  command=lambda: self.switch_translation_service('Google')).pack()
        tk.Button(settings_window, text='使用百度翻译, Use Baidu translate API', command=lambda: self.switch_translation_service('Baidu')).pack()

    def open_output_mode_dialog(self):
        self.output_mode_window = tk.Toplevel(self.root)
        self.output_mode_window.title('调整输出模式 adjust_output')

        tk.Label(self.output_mode_window, text='请输入括号样式（例如 [ 或 {）').pack()

        self.left_bracket_entry = tk.Entry(self.output_mode_window)
        self.left_bracket_entry.pack()
        self.left_bracket_entry.insert(0, self.bracket_style[0])

        self.right_bracket_entry = tk.Entry(self.output_mode_window)
        self.right_bracket_entry.pack()
        self.right_bracket_entry.insert(0, self.bracket_style[1])

        tk.Button(self.output_mode_window, text='保存 Save', command=self.save_bracket_style).pack()

    def on_right_click(self, event):
        try:
            # 获取选中的文本
            selected_text = self.preview_text.get(tk.SEL_FIRST, tk.SEL_LAST)
            # 更新右键菜单的搜索命令
            self.context_menu.entryconfigure("搜索图片", command=lambda: self.search_image(selected_text))
            self.context_menu.tk_popup(event.x_root, event.y_root)
        finally:
            self.context_menu.grab_release()

    def search_image(self, text):
        # 构建搜索URL并在浏览器中打开
        search_url = f"https://www.google.com/search?tbm=isch&q={text}"
        webbrowser.open_new_tab(search_url)

    def save_bracket_style(self):
        left_bracket = self.left_bracket_entry.get()
        right_bracket = self.right_bracket_entry.get()
        self.bracket_style = (left_bracket, right_bracket)
        self.output_mode_window.destroy()


if __name__ == '__main__':
    root = tk.Tk()
    root.title('RAD迭代原型Ver 0.31')
    app = KatakanaTranslatorApp(root)
    root.mainloop()
